/***********************************************************
 * File Name    : algo_ecg_calculate_hr.c
 * Description  : 心率计算
 * Author       : 
 * Create Date  : 
 * Last Modified: 
 * Version      : 
 * Note         : 通过波峰和波谷来计算心率
 ***********************************************************/
#include "algo_ecg_calculate_hr.h"
#include <stdio.h>

uint16_t minPeakDistance = 60;
uint16_t maxPeakDistance = 392;
uint16_t minPeakHeight   = 30;

uint32_t rri_avg = 0;
uint16_t hr = 0;
uint16_t RRI[20];
uint8_t RRI_index = 0;

static int8_t sign[2*256];
static uint16_t sign_len = 0;
static uint16_t indMax[10];
static uint8_t indMax_index = 0;
static uint16_t indMin[10];
static uint8_t indMin_index = 0;
static uint16_t rri_temp[10];
static uint8_t rri_temp_index = 0;

/**
 * @brief 
 * 
 * @param num ：输入数据，长度固定2*256
 * @param count 
 * @param minPeakDistance 
 * @param maxPeakDistance 
 * @param minPeakHeight 
 */
uint8_t findPeaks(float* num, uint16_t count)
{
    float diff = 0;
    for (uint16_t i = 1; i < count; i++) {
            /* 相邻值做差： *小于0，，赋-1 *大于0，赋1 *等于0，赋0 */
        diff = num[i] - num[i - 1];
        if (diff > 0) {
            sign[i] = 1;
        } else if (diff < 0) {
            sign[i] = -1;
        } else {
            sign[i] = 0;
        }
    }

    indMax_index = 0;
    indMin_index = 0;
    rri_temp_index = 0;

    uint16_t peak_poss      = 0;
    uint16_t peak_poss_last = 0;
    uint16_t peak_cnt = 0;
    int8_t diff1 = 0;
    for (uint16_t j = 1; j < count-1; j++) {
        diff1 = sign[j] - sign[j - 1];
        if (diff1 < 0) {
            if(peak_cnt == 0)//发现第一个波峰
            {
                if(num[j]>minPeakHeight)
                {
                    if(indMax_index >= 10)
                    {
                        return 0;
                    }
                    indMax[indMax_index++]=j;
                    peak_cnt++;
                    peak_poss = j;
                    peak_poss_last = peak_poss;
                }
            }
            else if(peak_cnt > 0)//不是第一个波峰，需要大于minPeakDistance
            {
                peak_poss = j;
                uint16_t distance = peak_poss-peak_poss_last;
                if(distance>=minPeakDistance && distance<=maxPeakDistance && num[j]>minPeakHeight)
                {
                    if(rri_temp_index>=10 || indMax_index>=10)
                    {
                        return 0;
                    }
                    rri_temp[rri_temp_index++]=distance+8;
                    indMax[indMax_index++]=j;
                    peak_cnt++;
                    peak_poss_last = peak_poss;
                }
            }
        } else if (diff1 > 0) {
            //indMin[indMin_index++]=j;
        }
    }

    RRI_index = 0;
    hr = 0;
    rri_avg = 0;
    uint8_t cnt = 0;
    for (uint8_t m = 0; m < rri_temp_index; m++) {
            rri_avg += rri_temp[m];
            RRI[RRI_index++]=rri_temp[m];
            cnt++;
    }
    if(cnt == 0)
    {
        return 0;
    }
    rri_avg = rri_avg/cnt;
    hr = (uint8_t) (Fs*60.0f/rri_avg);
    return hr;
} 
